﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace SocialApi.Instagram.Entities.Methods.Users
{
    /// <summary>
    /// Пользовательские методы
    /// </summary>
    public interface IUserMethods
    {
        /// <summary>
        /// Id пользователя
        /// </summary>
        [JsonProperty("id")]
        long Id { get; }

        /// <summary>
        /// Логин
        /// </summary>
        [JsonProperty("username")]
        string UserName { get; }

        /// <summary>
        /// Полное имя
        /// </summary>
        [JsonProperty("full_name")]
        string FullName { get; }

        /// <summary>
        /// Аватар пользователя
        /// </summary>
        [JsonProperty("profile_picture")]
        string ProfilePicture { get; }

        /// <summary>
        /// Биография
        /// </summary>
        [JsonProperty("bio")]
        string Biography { get; }

        /// <summary>
        /// Сайт пользователя
        /// </summary>
        [JsonProperty("website")]
        string Site { get; }

        /// <summary>
        /// Тип пользователя
        /// </summary>
        [JsonProperty("type")]
        string Type { get; }

        /// <summary>
        /// Количество медиа данных пользователя
        /// </summary>
        [JsonProperty("counts")]
        ICounts Counts { get; }

        /// <summary>
        /// Возвращает полную информацию о текущем пользователе
        /// </summary>
        IEnumerable<IResult> Feed();

        /// <summary>
        /// Возвращает полную информацию о текущем пользователе
        /// </summary>
        /// <param name="minId">Возвращает медиа элементы меньше <see cref="minId"/></param>
        /// <param name="maxId">Возвращает медиа элементы больше <see cref="maxId"/></param>
        IEnumerable<IResult> Feed(long minId, long maxId);

        /// <summary>
        /// Возвращает полную информацию о текущем пользователе
        /// </summary>
        /// <param name="count">Количество вовзращаемых медиа элементов</param>
        IEnumerable<IResult> Feed(int count);

        /// <summary>
        /// Возвращает полную информацию о текущем пользователе
        /// </summary>
        /// <param name="count">Количество вовзращаемых медиа элементов</param>
        /// <param name="minId">Возвращает медиа элементы меньше <see cref="minId"/></param>
        /// <param name="maxId">Возвращает медиа элементы больше <see cref="maxId"/></param>
        IEnumerable<IResult> Feed(int count, long minId, long maxId);

        /// <summary>
        /// Возвращает полную информацию о текущем пользователе
        /// </summary>
        Task<IEnumerable<IResult>> FeedAsync();

        /// <summary>
        /// Возвращает полную информацию о текущем пользователе
        /// </summary>
        /// <param name="minId">Возвращает медиа элементы меньше <see cref="minId"/></param>
        /// <param name="maxId">Возвращает медиа элементы больше <see cref="maxId"/></param>
        Task<IEnumerable<IResult>> FeedAsync(long minId, long maxId);

        /// <summary>
        /// Возвращает полную информацию о текущем пользователе
        /// </summary>
        /// <param name="count">Количество вовзращаемых медиа элементов</param>
        Task<IEnumerable<IResult>> FeedAsync(int count);

        /// <summary>
        /// Возвращает полную информацию о текущем пользователе
        /// </summary>
        /// <param name="count">Количество вовзращаемых медиа элементов</param>
        /// <param name="minId">Возвращает медиа элементы меньше <see cref="minId"/></param>
        /// <param name="maxId">Возвращает медиа элементы больше <see cref="maxId"/></param>
        Task<IEnumerable<IResult>> FeedAsync(int count, long minId, long maxId);

        /// <summary>
        /// Возвращает базовую информацию о текущем пользователе
        /// </summary>
        /// <returns>Базовая информация о пользователе</returns>
        IUserMethods Info();

        /// <summary>
        /// Возвращает базовую информацию о пользователе
        /// </summary>
        /// <param name="userId">Id пользователя, данные которого хотим узнать</param>
        /// <returns>Базовая информация о пользователе</returns>
        IUserMethods Info(long userId);

        /// <summary>
        /// Асинхроно возвращает базовую информацию о текущем пользователе
        /// </summary>
        Task<IUserMethods> InfoAsync();

        /// <summary>
        /// Асинхроно возвращает базовую информацию о пользователе
        /// </summary>
        /// <param name="userId">Id пользователя, данные которого хотим узнать</param>
        Task<IUserMethods> InfoAsync(long userId);

        /// <summary>
        /// Выполняет синхронный поиск пользователей
        /// </summary>
        /// <param name="query">Имя пользователя</param>
        IEnumerable<IUserMethods> Search(string query);

        /// <summary>
        /// Выполняет синхронный поиск пользователей
        /// </summary>
        /// <param name="query">Имя пользователя</param>
        /// <param name="count">Количество возвращемых пользователей</param>
        IEnumerable<IUserMethods> Search(string query, int count);

        /// <summary>
        /// Выполняет синхронный поиск пользователей
        /// </summary>
        /// <param name="query">Имя пользователя</param>
        Task<IEnumerable<IUserMethods>> SearchAsync(string query);

        /// <summary>
        /// Выполняет синхронный поиск пользователей
        /// </summary>
        /// <param name="query">Имя пользователя</param>
        /// <param name="count">Количество возвращемых пользователей</param>
        Task<IEnumerable<IUserMethods>> SearchAsync(string query, int count);

        /// <summary>
        /// Возвращает полную информация о понравишемся объекте
        /// </summary>
        /// <returns>Полная информация о понравишемся объекте</returns>
        IEnumerable<IResult> Liked();
     
        /// <summary>
        /// Возвращает полную информация о понравишемся объекте
        /// </summary>
        /// <param name="count">Количество, возвращаемых записей</param>
        /// <returns>Полная информация о понравишемся объекте</returns>
        IEnumerable<IResult> Liked(int count);

        /// <summary>
        /// Возвращает полную информация о понравишемся объекте
        /// </summary>
        /// <param name="maxLikeId">Возвращает записи меньше текущего Id</param>
        /// <returns>Полная информация о понравишемся объекте</returns>
        IEnumerable<IResult> Liked(long maxLikeId);

        /// <summary>
        /// Возвращает полную информация о понравишемся объекте
        /// </summary>
        /// <param name="count">Количество, возвращаемых записей</param>
        /// <param name="maxLikeId">Возвращает записи меньше текущего Id</param>
        /// <returns>Полная информация о понравишемся объекте</returns>
        IEnumerable<IResult> Liked(int count, long maxLikeId);

        /// <summary>
        /// Асинхронно возвращает полную информация о понравишемся объекте
        /// </summary>
        /// <returns>Полная информация о понравишемся объекте</returns>
        Task<IEnumerable<IResult>> LikedAsync();

        /// <summary>
        /// Асинхронно возвращает полную информация о понравишемся объекте
        /// </summary>
        /// <param name="count">Количество, возвращаемых записей</param>
        /// <returns>Полная информация о понравишемся объекте</returns>
        Task<IEnumerable<IResult>> LikedAsync(int count);

        /// <summary>
        /// Асинхронно возвращает полную информация о понравишемся объекте
        /// </summary>
        /// <param name="maxLikeId">Возвращает записи меньше текущего Id</param>
        /// <returns>Полная информация о понравишемся объекте</returns>
        Task<IEnumerable<IResult>> LikedAsync(long maxLikeId);

        /// <summary>
        /// Асинхронно возвращает полную информация о понравишемся объекте
        /// </summary>
        /// <param name="count">Количество, возвращаемых записей</param>
        /// <param name="maxLikeId">Возвращает записи меньше текущего Id</param>
        /// <returns>Полная информация о понравишемся объекте</returns>
        Task<IEnumerable<IResult>> LikedAsync(int count, long maxLikeId);

        /// <summary>
        /// возвращает последние файлы пользователя
        /// </summary>
        /// <returns>Последние файлы пользователя</returns>
        IEnumerable<IResult> Recent();

        /// <summary>
        /// возвращает последние файлы пользователя
        /// </summary>
        /// <param name="userId">Id пользователя</param>
        /// <returns>Последние файлы пользователя</returns>
        IEnumerable<IResult> Recent(long userId);
     
        /// <summary>
        /// возвращает последние файлы пользователя
        /// </summary>
        /// <param name="count">Количество, возвращаемых данных</param>
        /// <returns>Последние файлы пользователя</returns>
        IEnumerable<IResult> Recent(int count);

        /// <summary>
        /// возвращает последние файлы пользователя
        /// </summary>
        /// <param name="userId">Id пользователя</param>
        /// <param name="count">Количество, возвращаемых данных</param>
        /// <returns>Последние файлы пользователя</returns>
        IEnumerable<IResult> Recent(long userId, int count);
        
        /// <summary>
        /// возвращает последние файлы пользователя
        /// </summary>
        /// <param name="minId">Возвращает данные меньше заданного Id</param>
        /// <param name="maxId">Возвращает данные больше заданного Id</param>
        /// <returns>Последние файлы пользователя</returns>
        IEnumerable<IResult> Recent(long minId, long maxId);

        /// <summary>
        /// возвращает последние файлы пользователя
        /// </summary>
        /// <param name="userId">Id пользователя</param>
        /// <param name="minId">Возвращает данные меньше заданного Id</param>
        /// <param name="maxId">Возвращает данные больше заданного Id</param>
        /// <returns>Последние файлы пользователя</returns>
        IEnumerable<IResult> Recent(long userId, long minId, long maxId);

        /// <summary>
        /// возвращает последние файлы пользователя
        /// </summary>
        /// <param name="count">Количество, возвращаемых данных</param>
        /// <param name="minId">Возвращает данные меньше заданного Id</param>
        /// <param name="maxId">Возвращает данные больше заданного Id</param>
        /// <returns>Последние файлы пользователя</returns>
        IEnumerable<IResult> Recent(int count, long minId, long maxId);

        /// <summary>
        /// возвращает последние файлы пользователя
        /// </summary>
        /// <param name="userId">Id пользователя</param>
        /// <param name="count">Количество, возвращаемых данных</param>
        /// <param name="minId">Возвращает данные меньше заданного Id</param>
        /// <param name="maxId">Возвращает данные больше заданного Id</param>
        /// <returns>Последние файлы пользователя</returns>
        IEnumerable<IResult> Recent(long userId, int count, long minId, long maxId);
        
        /// <summary>
        /// возвращает последние файлы пользователя
        /// </summary>
        /// <param name="min">Возвращает данные, после текущего времени</param>
        /// <param name="max">Возвращает данные, до текущего времени</param>
        /// <returns>Последние файлы пользователя</returns>
        IEnumerable<IResult> Recent(DateTime? min, DateTime? max);

        /// <summary>
        /// возвращает последние файлы пользователя
        /// </summary>
        /// <param name="userId">Id пользователя</param>
        /// <param name="min">Возвращает данные, после текущего времени</param>
        /// <param name="max">Возвращает данные, до текущего времени</param>
        /// <returns>Последние файлы пользователя</returns>
        IEnumerable<IResult> Recent(long userId, DateTime? min, DateTime? max);
        
        /// <summary>
        /// возвращает последние файлы пользователя
        /// </summary>
        /// <param name="count">Количество, возвращаемых данных</param>
        /// <param name="min">Возвращает данные, после текущего времени</param>
        /// <param name="max">Возвращает данные, до текущего времени</param>
        /// <returns>Последние файлы пользователя</returns>
        IEnumerable<IResult> Recent(int count, DateTime? min, DateTime? max);

        /// <summary>
        /// возвращает последние файлы пользователя
        /// </summary>
        /// <param name="userId">Id пользователя</param>
        /// <param name="count">Количество, возвращаемых данных</param>
        /// <param name="min">Возвращает данные, после текущего времени</param>
        /// <param name="max">Возвращает данные, до текущего времени</param>
        /// <returns>Последние файлы пользователя</returns>
        IEnumerable<IResult> Recent(long userId, int count, DateTime? min, DateTime? max);
        
        /// <summary>
        /// возвращает последние файлы пользователя
        /// </summary>
        /// <param name="minId">Возвращает данные меньше заданного Id</param>
        /// <param name="maxId">Возвращает данные больше заданного Id</param>
        /// <param name="min">Возвращает данные, после текущего времени</param>
        /// <param name="max">Возвращает данные, до текущего времени</param>
        /// <returns>Последние файлы пользователя</returns>
        IEnumerable<IResult> Recent(long minId, long maxId, DateTime? min, DateTime? max);

        /// <summary>
        /// возвращает последние файлы пользователя
        /// </summary>
        /// <param name="userId">Id пользователя</param>
        /// <param name="minId">Возвращает данные меньше заданного Id</param>
        /// <param name="maxId">Возвращает данные больше заданного Id</param>
        /// <param name="min">Возвращает данные, после текущего времени</param>
        /// <param name="max">Возвращает данные, до текущего времени</param>
        /// <returns>Последние файлы пользователя</returns>
        IEnumerable<IResult> Recent(long userId, long minId, long maxId, DateTime? min, DateTime? max);
        
        /// <summary>
        /// возвращает последние файлы пользователя
        /// </summary>
        /// <param name="count">Количество, возвращаемых данных</param>
        /// <param name="minId">Возвращает данные меньше заданного Id</param>
        /// <param name="maxId">Возвращает данные больше заданного Id</param>
        /// <param name="min">Возвращает данные, после текущего времени</param>
        /// <param name="max">Возвращает данные, до текущего времени</param>
        /// <returns>Последние файлы пользователя</returns>
        IEnumerable<IResult> Recent(int count, long minId, long maxId, DateTime? min, DateTime? max);

        /// <summary>
        /// возвращает последние файлы пользователя
        /// </summary>
        /// <param name="userId">Id пользователя</param>
        /// <param name="count">Количество, возвращаемых данных</param>
        /// <param name="minId">Возвращает данные меньше заданного Id</param>
        /// <param name="maxId">Возвращает данные больше заданного Id</param>
        /// <param name="min">Возвращает данные, после текущего времени</param>
        /// <param name="max">Возвращает данные, до текущего времени</param>
        /// <returns>Последние файлы пользователя</returns>
        IEnumerable<IResult> Recent(long userId, int count, long minId, long maxId, DateTime? min, DateTime? max);

        /// <summary>
        /// Асинхронно возвращает последние файлы пользователя
        /// </summary>
        /// <returns>Последние файлы пользователя</returns>
        Task<IEnumerable<IResult>> RecentAsync();

        /// <summary>
        /// Асинхронно возвращает последние файлы пользователя
        /// </summary>
        /// <param name="userId">Id пользователя</param>
        /// <returns>Последние файлы пользователя</returns>
        Task<IEnumerable<IResult>> RecentAsync(long userId);

        /// <summary>
        /// Асинхронно возвращает последние файлы пользователя
        /// </summary>
        /// <param name="count">Количество, возвращаемых данных</param>
        /// <returns>Последние файлы пользователя</returns>
        Task<IEnumerable<IResult>> RecentAsync(int count);

        /// <summary>
        /// Асинхронно возвращает последние файлы пользователя
        /// </summary>
        /// <param name="userId">Id пользователя</param>
        /// <param name="count">Количество, возвращаемых данных</param>
        /// <returns>Последние файлы пользователя</returns>
        Task<IEnumerable<IResult>> RecentAsync(long userId, int count);

        /// <summary>
        /// Асинхронно возвращает последние файлы пользователя
        /// </summary>
        /// <param name="minId">Возвращает данные меньше заданного Id</param>
        /// <param name="maxId">Возвращает данные больше заданного Id</param>
        /// <returns>Последние файлы пользователя</returns>
        Task<IEnumerable<IResult>> RecentAsync(long minId, long maxId);

        /// <summary>
        /// Асинхронно возвращает последние файлы пользователя
        /// </summary>
        /// <param name="userId">Id пользователя</param>
        /// <param name="minId">Возвращает данные меньше заданного Id</param>
        /// <param name="maxId">Возвращает данные больше заданного Id</param>
        /// <returns>Последние файлы пользователя</returns>
        Task<IEnumerable<IResult>> RecentAsync(long userId, long minId, long maxId);

        /// <summary>
        /// Асинхронно возвращает последние файлы пользователя
        /// </summary>
        /// <param name="count">Количество, возвращаемых данных</param>
        /// <param name="minId">Возвращает данные меньше заданного Id</param>
        /// <param name="maxId">Возвращает данные больше заданного Id</param>
        /// <returns>Последние файлы пользователя</returns>
        Task<IEnumerable<IResult>> RecentAsync(int count, long minId, long maxId);

        /// <summary>
        /// Асинхронно возвращает последние файлы пользователя
        /// </summary>
        /// <param name="userId">Id пользователя</param>
        /// <param name="count">Количество, возвращаемых данных</param>
        /// <param name="minId">Возвращает данные меньше заданного Id</param>
        /// <param name="maxId">Возвращает данные больше заданного Id</param>
        /// <returns>Последние файлы пользователя</returns>
        Task<IEnumerable<IResult>> RecentAsync(long userId, int count, long minId, long maxId);

        /// <summary>
        /// Асинхронно возвращает последние файлы пользователя
        /// </summary>
        /// <param name="min">Возвращает данные, после текущего времени</param>
        /// <param name="max">Возвращает данные, до текущего времени</param>
        /// <returns>Последние файлы пользователя</returns>
        Task<IEnumerable<IResult>> RecentAsync(DateTime? min, DateTime? max);

        /// <summary>
        /// Асинхронно возвращает последние файлы пользователя
        /// </summary>
        /// <param name="userId">Id пользователя</param>
        /// <param name="min">Возвращает данные, после текущего времени</param>
        /// <param name="max">Возвращает данные, до текущего времени</param>
        /// <returns>Последние файлы пользователя</returns>
        Task<IEnumerable<IResult>> RecentAsync(long userId, DateTime? min, DateTime? max);

        /// <summary>
        /// Асинхронно возвращает последние файлы пользователя
        /// </summary>
        /// <param name="count">Количество, возвращаемых данных</param>
        /// <param name="min">Возвращает данные, после текущего времени</param>
        /// <param name="max">Возвращает данные, до текущего времени</param>
        /// <returns>Последние файлы пользователя</returns>
        Task<IEnumerable<IResult>> RecentAsync(int count, DateTime? min, DateTime? max);

        /// <summary>
        /// Асинхронно возвращает последние файлы пользователя
        /// </summary>
        /// <param name="userId">Id пользователя</param>
        /// <param name="count">Количество, возвращаемых данных</param>
        /// <param name="min">Возвращает данные, после текущего времени</param>
        /// <param name="max">Возвращает данные, до текущего времени</param>
        /// <returns>Последние файлы пользователя</returns>
        Task<IEnumerable<IResult>> RecentAsync(long userId, int count, DateTime? min, DateTime? max);

        /// <summary>
        /// Асинхронно возвращает последние файлы пользователя
        /// </summary>
        /// <param name="minId">Возвращает данные меньше заданного Id</param>
        /// <param name="maxId">Возвращает данные больше заданного Id</param>
        /// <param name="min">Возвращает данные, после текущего времени</param>
        /// <param name="max">Возвращает данные, до текущего времени</param>
        /// <returns>Последние файлы пользователя</returns>
        Task<IEnumerable<IResult>> RecentAsync(long minId, long maxId, DateTime? min, DateTime? max);

        /// <summary>
        /// Асинхронно возвращает последние файлы пользователя
        /// </summary>
        /// <param name="userId">Id пользователя</param>
        /// <param name="minId">Возвращает данные меньше заданного Id</param>
        /// <param name="maxId">Возвращает данные больше заданного Id</param>
        /// <param name="min">Возвращает данные, после текущего времени</param>
        /// <param name="max">Возвращает данные, до текущего времени</param>
        /// <returns>Последние файлы пользователя</returns>
        Task<IEnumerable<IResult>> RecentAsync(long userId, long minId, long maxId, DateTime? min, DateTime? max);

        /// <summary>
        /// Асинхронно возвращает последние файлы пользователя
        /// </summary>
        /// <param name="count">Количество, возвращаемых данных</param>
        /// <param name="minId">Возвращает данные меньше заданного Id</param>
        /// <param name="maxId">Возвращает данные больше заданного Id</param>
        /// <param name="min">Возвращает данные, после текущего времени</param>
        /// <param name="max">Возвращает данные, до текущего времени</param>
        /// <returns>Последние файлы пользователя</returns>
        Task<IEnumerable<IResult>> RecentAsync(int count, long minId, long maxId, DateTime? min, DateTime? max);

        /// <summary>
        /// Асинхронно возвращает последние файлы пользователя
        /// </summary>
        /// <param name="userId">Id пользователя</param>
        /// <param name="count">Количество, возвращаемых данных</param>
        /// <param name="minId">Возвращает данные меньше заданного Id</param>
        /// <param name="maxId">Возвращает данные больше заданного Id</param>
        /// <param name="min">Возвращает данные, после текущего времени</param>
        /// <param name="max">Возвращает данные, до текущего времени</param>
        /// <returns>Последние файлы пользователя</returns>
        Task<IEnumerable<IResult>> RecentAsync(long userId, int count, long minId, long maxId, DateTime? min, DateTime? max);
    }
}